package com.aynu.queue;

/**
 * 循环数组队列：对上一个数据模拟队列的优化，解决了队列只能使用一次的问题（全部插入后成功后，在删除，再次插入，队列无法插入）
 * 
 * @author 马军
 *
 */
public class CircleArrayQueueTest {
	public static void main(String[] args) {
		CircleArrayQueue circle = new CircleArrayQueue(3);
		circle.addQueue(12);
		circle.addQueue(13);
//		circle.addQueue(14);
		System.out.println(circle.getQueue());
		circle.addQueue(15);
		System.out.println(circle.getQueue());
		circle.addQueue(16);
		circle.getAllQueue();
		System.out.println(circle.headQueue());
	}
}

//使用数组模拟队列-编写一个ArrayQueue类
class CircleArrayQueue {
	private int maxSize;// 数组的最大容量
	private int front;// 队列头:指向数组的第一个元素，默认值为：0
	private int rear;// 队列尾：指向数组的最后一个元素的下一个位置，因为希望空出一个空间，作为约定，默认值为：0
	private int[] arr;// 该数组用于存放队列，模拟队列

	// 创建队列构造器
	public CircleArrayQueue() {
		this(10);
	}

	public CircleArrayQueue(int maxSize) {
		this.maxSize = maxSize;
		arr = new int[this.maxSize];
		front = 0;// 数组属性有默认值，可以不写
		rear = 0;// 数组属性有默认值，可以不写
	}

	// 判断队列是否满的
	public boolean isFull() {
		return (rear + 1) % maxSize == front;
	}

	// 判定队列是否空
	public boolean isEmpty() {
		return rear == front;
	}

	// 添加数据到队列
	public void addQueue(int n) {
		if (isFull()) {
			throw new RuntimeException("队列满了，不能新增数据");
		}
		// 直接将数据加入
		arr[rear] = n;
		// 将rear往后移，这里必须考虑取模
		rear = (rear + 1) % maxSize;
	}

	// 获取队列的数据，出队列
	public int getQueue() {
		// 判断是否为空
		if (isEmpty()) {
			throw new RuntimeException("队列为空，不能取数据");
		}
		// 这里分析出front是指向队列的第一个元素
		// 1.先把front对应的值保留到一个临时变量
		// 2.将front后移
		// 3.将临时保存的变量后移
		int num = arr[front];
		front++;
		return num;
	}

	// 显示队列的所有数据
	public void getAllQueue() {
		if (isEmpty()) {
			throw new RuntimeException("队列为空，不能取数据");
		}
		// 从front头节点开始遍历
		for (int i = front; i < front + size(); i++) {
			System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]);
		}
	}

	// 获取当前数组的实际的元素的个数
	public int size() {
		return (rear - front + maxSize) % maxSize;
	}

	// 显示队列头数据，注意不是取数据
	public int headQueue() {
		if (isEmpty()) {
			throw new RuntimeException("队列为空，不能取数据");
		}
		return arr[front];
	}

}